﻿/********************************************************************************
** 作者： Mick
** 邮箱： zheng_jinfan@126.com
** 主页： http://www.zhengjinfan.cn
** 创始时间：2016-2-17
** 描述：
**      [辅助类]用户请求辅助类
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using BestEasyCMS.Framework.Extension;

namespace BestEasyCMS.Framework.Util
{
    /// <summary>
    /// [辅助类]用户请求辅助类
    /// </summary>
    public sealed class RequestUtil
    {
        #region 根据单一模式构建类的对象

        //私有构造函数

        private static RequestUtil _object; //静态变量
        private readonly static Object _obj = new object();
        private RequestUtil()
        {
        }

        /// <summary>
        /// 提供类的实例属性
        /// </summary>
        public static RequestUtil Instance
        {
            get
            {
                lock (_obj)
                {
                    return _object ?? (_object = new RequestUtil());
                }
            }
        }

        #endregion

        /// <summary>
        /// 判断当前页面是否接收到了Post请求
        /// </summary>
        /// <returns>是否接收到了Post请求</returns>
        public bool IsPost()
        {
            return HttpContext.Current.Request.HttpMethod.Equals("POST");
        }

        /// <summary>
        /// 判断当前页面是否接收到了Get请求
        /// </summary>
        /// <returns>是否接收到了Get请求</returns>
        public bool IsGet()
        {
            return HttpContext.Current.Request.HttpMethod.Equals("GET");
        }

        /// <summary>
        /// 创建默认的应用程序名称，如“/”或“/website/”
        /// </summary>
        public string GetAppName()
        {
            string path = HttpContext.Current.Request.ApplicationPath;
            if (path != null && path.Trim() != "/") //判断路径是否为“/”
            {
                path += "/";
            }
            return path;

            //string appName = System.Web.HttpRuntime.AppDomainAppVirtualPath + "/";
            //if (string.IsNullOrEmpty(appName))
            //    return "/";

            //return appName;
        }

        /// <summary>
        /// 获得Url或表单参数的值, 先判断Url参数是否为空字符串, 如为True则返回表单参数的值
        /// </summary>
        /// <param name="strName">参数</param>
        /// <returns>Url或表单参数的值</returns>
        public string GetString(string strName)
        {
            if ("".Equals(GetQueryString(strName)))
            {
                return GetFormString(strName);
            }
            return GetQueryString(strName);
        }

        /// <summary>
        /// 获得指定Url参数的值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <returns>Url参数的值</returns>
        public string GetQueryString(string strName)
        {
            if (HttpContext.Current.Request.QueryString[strName] == null)
            {
                return String.Empty;
            }
            return HttpContext.Current.Request.QueryString[strName];
        }

        /// <summary>
        /// 获得指定Url参数的int类型值
        /// </summary>
        /// <param name="strName">Url参数</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>Url参数的int类型值</returns>
        public static int GetQueryInt(string strName, int defValue)
        {
            return StrToInt(HttpContext.Current.Request.QueryString[strName], defValue);
        }

        /// <summary>
        /// 将对象转换为Int32类型
        /// </summary>
        /// <param name="expression">要转换的字符串</param>
        /// <param name="defValue">缺省值</param>
        /// <returns>转换后的int类型结果</returns>
        private static int StrToInt(object expression, int defValue)
        {
            if (expression != null)
            {
                string str = expression.ToString();
                if (str.Length > 0 && str.Length <= 11 && Regex.IsMatch(str, @"^[-]?[0-9]*$"))
                {
                    if ((str.Length < 10) || (str.Length == 10 && str[0] == '1') ||
                        (str.Length == 11 && str[0] == '-' && str[1] == '1'))
                    {
                        return Convert.ToInt32(str);
                    }
                }
            }
            return defValue;
        }

        /// <summary>
        /// 获得指定表单参数的值
        /// </summary>
        /// <param name="strName">表单参数</param>
        /// <returns>表单参数的值</returns>
        public string GetFormString(string strName)
        {
            if (HttpContext.Current.Request.Form[strName] == null)
            {
                return "";
            }
            return HttpContext.Current.Request.Form[strName];
        }

        /// <summary>
        /// 返回上一个页面的地址
        /// </summary>
        /// <returns>上一个页面的地址</returns>
        public string GetUrlReferrer()
        {
            string retVal = null;

            try
            {
                if (HttpContext.Current.Request.UrlReferrer != null)
                    retVal = HttpContext.Current.Request.UrlReferrer.ToString();
            }
            catch (Exception)
            {
                throw new Exception();
            }

            return retVal ?? "";
        }

        /// <summary>
        /// 判断当前访问是否来自浏览器软件
        /// </summary>
        /// <returns>当前访问是否来自浏览器软件</returns>
        public bool IsBrowserGet()
        {
            string[] browserName = { "ie", "opera", "netscape", "mozilla", "konqueror", "firefox" };
            string curBrowser = HttpContext.Current.Request.Browser.Type.ToLower();
            return browserName.Any(t => curBrowser.IndexOf(t, StringComparison.Ordinal) >= 0);
        }

        /// <summary>
        /// 取当前主机头地址,有站点名的会带上站点名（即虚拟目录名），不以"/"结尾
        /// </summary>
        /// <returns></returns>
        public string GetHttpUrl()
        {
            string url = HttpContext.Current.Request.ServerVariables["HTTP_HOST"];
            url = url.ToLower().Replace("http://", "").Trim('/').Trim('\\');
            string applicationPath = HttpContext.Current.Request.ApplicationPath.ToStr(); //站点名(虚拟目录名)  

            url = "http://" + url + applicationPath;


            return url;
        }

        /// <summary>
        /// 在当前页面路径上添加参数, 若已有此参数则修改
        /// </summary>
        /// <param name="parmName"></param>
        /// <param name="parmValue"></param>
        /// <returns></returns>
        public string AddParm(string parmName, string parmValue)
        {
            var dict = new Dictionary<string, string> { { parmName, parmValue } };
            string result = AddParm(dict);
            return result;
        }

        /// <summary>
        /// 在当前页面路径上添加参数, 若已有此参数则修改
        /// </summary>
        /// <param name="dict">更改的参数集合</param>
        /// <returns></returns>
        public string AddParm(Dictionary<string, string> dict)
        {
            string newQueryString = "";

            NameValueCollection queryString = HttpContext.Current.Request.QueryString;

            for (int i = 0; i < queryString.Count; i++)
            {
                if (dict.Count(p => p.Key.ToLower() == queryString.Keys[i].ToStr().ToLower()) > 0)
                    continue;
                if (queryString.Keys[i].ToStr().IsEmpty() || queryString[i].ToStr().IsEmpty())
                    continue;

                newQueryString += "{0}={1}&".FormatWith(queryString.Keys[i].ToStr(), queryString[i].ToStr());
            }

            newQueryString = dict.Aggregate(newQueryString, (current, item) => current + "{0}={1}&".FormatWith(item.Key, item.Value));

            newQueryString = newQueryString.TrimEnd('&');

            string pagePath = HttpContext.Current.Request.Path;
            newQueryString = "{0}?{1}".FormatWith(pagePath, newQueryString);
            return newQueryString;
        }

        /// <summary>
        /// 在已有URL访问地址上添加参数，若已有此参数则修改
        /// </summary>
        /// <param name="url">已有的URL访问地址</param>
        /// <param name="dict">更改或添加的参数集合</param>
        /// <returns></returns>
        public string AddParm(string url, Dictionary<string, string> dict)
        {
            foreach (var kv in dict)
            {
                var reg = new Regex("(^|\\?|&)" + kv.Key + "=\\d*(&|$)");
                Match m = reg.Match(url);
                if (m.Success)
                {
                    string temp = m.Value.Trim('&').Trim('?');
                    url = url.Replace(temp, kv.Key + "=" + kv.Value);
                }
                else
                {
                    if (url.Contains("?"))
                        url += "&{0}={1}".FormatWith(kv.Key, kv.Value);
                    else
                        url += "?{0}={1}".FormatWith(kv.Key, kv.Value);
                }
            }
            return url;
        }
    }
}